﻿using System;
using System.Reflection;
using System.Web.Compilation;
using System.Web.UI.WebControls;

using LeanEngine.Extensions;
using LeanEngine.Collections;
using LeanEngine.Validation;
using System.Globalization;
using LeanEngine.Exception;

namespace LeanEngine.Validation.Web.UI
{
    /// <summary>
    /// Performs validation on a control's value using the validation specified on the property of <see cref="System.Type"/>.
    /// </summary>
    public sealed class PropertyValidator : BaseValidator
    {
        #region PropertyInfo Members

        /// <summary>
        /// Get or sets the name of the property that holds the validators.
        /// </summary>
        public string PropertyName { get; set; }

        /// <summary>
        /// Gets or sets the name of the type to use a source for validation specifications.
        /// </summary>
        public string SourceTypeName { get; set; }

        #endregion

        #region BaseValidator Members

        /// <summary>
        /// Determines whether the content in the input control is valid.
        /// </summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <returns><see langword="true"/> if the control is valid; otherwise, <see langword="false"/>.</returns>
        protected override bool EvaluateIsValid()
        {
            var value = this.GetControlValidationValue(this.ControlToValidate);
            var dtoType = BuildManager.GetType(this.SourceTypeName, false, false);
            if (dtoType.IsNull()) throw new InvalidOperationException("Could not found type " + this.SourceTypeName + ".");

            var property = dtoType.GetProperty(this.PropertyName);
            var validationList = ValidatorMetadataCache.GetValidatorList(property);
            if (validationList.Count == 0)
            {
                return true;
            }
            else
            {
                try
                {
                    return LeanEngine.Validation.ValidationHelper.Validate(value, validationList);
                }
                catch (BusinessException ex)
                {
                    this.ErrorMessage = ex.Message;
                    this.ToolTip = ex.Message;

                    return false;
                }
            }
        }

        #endregion
    }
}
